<?php 
//wymagane do www2gg
define("GG_WELCOME",			0x0001);
define("GG_LOGIN",  			0x000c);
define("GG_LOGIN60",  			0x0015);
define("GG_LOGIN_OK",			0x0003);
define("GG_LOGIN_FAILED",		0x0009);
define("GG_NEW_STATUS",			0x0002);
define("GG_STATUS",	    		0x0002);
define("GG_STATUS_NOT_AVAIL",	0x0001);
define("GG_STATUS_NOT_AVAIL_DESCR",	0x0015);
define("GG_STATUS_AVAIL",		0x0002);
define("GG_STATUS_AVAIL_DESCR",	0x0004);
define("GG_STATUS_BUSY",		0x0003);
define("GG_STATUS_BUSY_DESCR",	0x0005);
define("GG_STATUS_INVISIBLE",	0x0014);
define("GG_NOTIFY",             0x0010);
define("GG_NOTIFY_REPLY",		0x000c);
define("GG_NOTIFY_REPLY60",		0x0011);
define("GG_USER_NORMAL",		0x0003);
define("GG_USER_BLOCKED",		0x0004);
define("GG_SEND_MSG",			0x000b);
define("GG_CLASS_MSG",			0x0004);
define("GG_CLASS_CHAT",			0x0008);
define("GG_CLASS_ACK",          0x0020);
define("GG_SEND_MSG_ACK",		0x0005);
define("GG_ACK_DELIVERED",		0x0002);
define("GG_ACK_QUEUED",			0x0003);
define("GG_RECV_MSG",			0x000a);
define("GG_LOGIN_FAILED2",		0x000B);
define("GG_ACK_MBOXFULL",		0x0004);
define("DISCONNECTED",          0x0100);
define("GG_PUBDIR50_REQUEST",   0x0014);
define("GG_PUBDIR50_REPLY",     0x000e);
define("GG_PUBDIR50_SEARCH",    0x0003);

class GaduGadu
{
  var $fp;	                            // polaczenie w sesji gadu-gadu
  var $wiadomosci = array();            // tablica z odebranymi wiadomosciami
  var $status_kontaktu = array();       // odebrane dane adresata wiadomosci
  var $status_dostarczenia = array();   // tablica ze stanami dostarczenia wiadomosci
  var $wyniki_szukania = array();	    // wyniki wyszukiwania w katalogu
  var $debug = TRUE;                   // tryb debug
    
  function GaduGadu() // konstruktor 
  {
      mt_srand((double)microtime() * 1000000);
  }
  
  // zwraca stan dostarczenia wiadomosci o danym seq
  function status_dostarczenia ($seq)
  {
      if ($this->status_dostarczenia[$seq])
          return $this->status_dostarczenia[$seq];
      else
          return 0;
  }
 
  
  // wersje gadu gadu > 0x14 (4.8.9, 4.9.2, 5.x itp.) 
  function oblicz_nowy_hash ($haslo, $klucz) {  //takie efekty bitwy z php i jego signed int ;-)
	
    $x0=0; $x1=0; $y0=0; $y1=0; $z=0; $tmp=0;
    $y0 = ($klucz << 16) >> 16; $y1 = $klucz >> 16 ;

    for ($i=0; $i<strlen($haslo); $i++) {
        $x0 = ($x0 & 0xFF00) | ord($haslo[$i]); $x1 &= 0xFFFF;
    	$y0 ^= $x0; $y1 ^= $x1;
        $y0 += $x0; $y1 += $x1;
    	$x1 <<= 8; $x1 |= ($x0 >> 8); $x0 <<= 8;
        $y0 ^= $x0; $y1 ^= $x1;
    	$x1 <<= 8; $x1 |= ($x0 >> 8); $x0 <<= 8;
        $y0 -= $x0; $y1 -= $x1;
        $x1 <<= 8; $x1 |= ($x0 >> 8); $x0 <<= 8;
        $y0 ^= $x0; $y1 ^= $x1;
        $z = $y0 & 0x1F;

        $y0 &= 0xFFFF; $y1 &= 0xFFFF;
        if ($z <= 16) {
    	    $tmp= ($y1 << $z) | ($y0 >> (16-$z));
    	    $y0 = ($y1 >> (16-$z)) | ($y0 << $z);
            $y1 = $tmp;    
        } else {
    	    $tmp= $y0 << ($z-16);
    	    $y0 = ($y0 >> (32-$z)) | ( (($y1 << $z) >> $z) << ($z-16) );
            $y1 = ($y1 >> (32-$z)) | $tmp;
    	}
    	$y0 &= 0xFFFF; $y1 &= 0xFFFF;
    }
    $hash = hexdec(sprintf("%04x%04x", $y1, $y0));
    settype($hash, 'integer');

  return $hash;
  }

  function znajdz_serwer($numer)
  {
    $http_fp = @fsockopen("appmsg.gadu-gadu.pl", 80, $errno, $errstr, 3); //timeout=3s
    if (!$http_fp) {
	$this->Debug
        ("BRAK POLACZENA Z APPMSG.GADU-GADU.PL, MOZE BYC PRZECIAZONY: $errno - $errstr<BR>\n");
    } else {
        $get = "GET /appsvc/appmsg.asp?fmnumber=<$numer> HTTP/1.0\r\n";
        $get.= "Host: appmsg.gadu-gadu.pl\r\n";
        $get.= "User-Agent: Mozilla/4.7 [en] (Win98; I)\r\n";
        $get.= "Pragma: no-cache\r\n\r\n";
        fputs($http_fp, $get);
        fgets($http_fp, 128); fgets($http_fp, 128); $tmp = fgets($http_fp, 128); // 3 linijka
        fclose($http_fp);
        if (preg_match("/\s([\d\.]{8,16})\:([\d]{1,5})\s/", $tmp, $addres)) {
            $host = $addres[1];
            $port = $addres[2];
            $this->Debug("Uzyskano adres hosta z appmsg.gadu-gadu.pl: ".$host.":".$port);

            return array ($host, $port);
        }
    }
    # Losowanie jednego z hostow gadu-gadu w przypadku gdy nie udaje sie uzyska�
    # adresu hosta z appmsg.gadu-gadu.pl, ta lista mo�e si� w przysz�o�ci zmieni�
    $ip = array(85, 86, 88, 89); 
    $host = '217.17.41.'.$ip[rand(0,sizeof($ip)-1)];
    $port = 8074;
    $this->Debug ("Nie udalo sie uzyskac hosta od appmsg uzyto domyslnego $host:$port");

  return array ($host, $port);
  }

  function login($numer, $haslo, $host, $port, $opis = "", $wersja = 0x22)
  {
    $this->fp = @fsockopen($host, $port, $errno, $errstr, 10); //timeout = 10s
    $this->Debug("Logowanie do $host:$port ...");
    if (!$this->fp) {
        $this->Debug("PROBLEM Z POLACZENIEM: $errno - $errstr<BR>\n");
        return DISCONNECTED;
    }

    if (!$data = fread($this->fp, 12)) {
        $this->Debug("Polaczenie nieoczekiwanie zamkniete<BR>\n");
        return DISCONNECTED;
    }
    $tab = unpack("Vtyp/Vrozmiar/Vklucz", $data);
    $this->Debug("Otrzymano pakiet z kluczem hasla: ", $tab, bin2hex($data));
    // wersja - 0x16-GG 4.9.x, 0x19-5.0.3
    $hash = $this->oblicz_nowy_hash($haslo, $tab['klucz']); //dla wersji gg >= 0x14
    $this->Debug("Obliczono hash hasla ");
    
	$data = pack("VVVVVVvVvVvCCa".strlen($opis), GG_LOGIN60, 0x20 + strlen($opis), $numer, $hash, ($opis)?GG_STATUS_AVAIL_DESCR:GG_STATUS_AVAIL, $wersja, 0, 0, 0, 0, 0, 0x14, 0xbe , $opis );

    fwrite($this->fp, $data);

    $this->Debug("Wyslano pakiet logowania: ".bin2hex($data));
    # Przy podaniu zlego hasla moze natychmiast zerwac polaczenie
    if (!$data1 = fread($this->fp, 8))
    	return GG_LOGIN_FAILED2;

    $tab = unpack("Vlogin_status/Vrozmiar", $data1);
    $this->Debug("Odpowiedz na logowanie ", $tab);
    
  return $tab['login_status'];     //Wynik logowania GG_LOGIN_OK lub GG_LOGIN_FAILED
  }


  function wyslij_liste_kontaktow ($uin)
  {
    // lista kontak�w z jednym numerem 
    $data = pack ("VVVC",GG_NOTIFY, 5, $uin, GG_USER_NORMAL);
    $this->Debug("Wyslano liste kontaktow".bin2hex($data));
  
  return fwrite($this->fp,$data);
  }

  function wyslij_wiadomosc($adresat, $tresc, $potwierdzenie = false)
  {
    $tresc = txt::iso2cp($tresc);
    $seq = mt_rand();
    
    $data = pack("VVVVVa".strlen($tresc)."C", GG_SEND_MSG, 0x0d + strlen($tresc), $adresat,
		 $seq,  ($potwierdzenie)?GG_CLASS_MSG:GG_CLASS_MSG | GG_CLASS_ACK, $tresc, 0);
    $this->Debug("Wyslano pakiet wiadomo�ci : ".bin2hex($data), $data);
    
    $this->status_dostarczenia[$seq] = FALSE; //zmieni sie przy otrzymaniu potwierdzenia
    
    if (!fwrite($this->fp, $data)) 
      return FALSE;

  return $seq;
  }

  function odbierz_dane ($auto_odpowiedz = "")
  { 
    if (!$data = fread($this->fp, 8))
        return FALSE;
    $tab = unpack("Vtyp/Vrozmiar", $data);
   

    # Odebranie wszystkich oczekujacych wiadomosci
    while ($tab['typ'] == GG_RECV_MSG || $tab['typ'] == GG_NOTIFY_REPLY60 
            || $tab['typ'] == GG_STATUS) {
        $data = fread($this->fp, $tab['rozmiar']);

        switch($tab['typ']) {
          case GG_RECV_MSG:
	        $tab = unpack("Vnadawca/Vseq/Vtime/Vclass/A*wiadomosc", $data);
            $this->Debug("Otrzymano wiadomosc ", $tab);
            array_push($this->wiadomosci, $tab);
            // dostałem jakas wiadomosc, moze cos z nia zrobic!?
            print_r($tab);
            
	        break;
          case GG_STATUS:
          case GG_NOTIFY_REPLY60:
	        $this->Debug ("Otrzymano odpowiedz ze statusem kontaktu ".bin2hex($data));
        	$tab = unpack("Vuin/Vstatus", $data); 
			$tab['uin'] = $tab['uin'] & 0xFFFFFF;
        	$this->status_kontaktu[$tab['uin']] = $data;
        	$this->Debug ($tab, $this->status_kontaktu);
        	break;
	    }

    	$data = fread($this->fp, 8);
    	$tab = unpack("Vtyp/Vrozmiar", $data);
    }

    # odebranie ostatnich pakiet�w
    if (!$data = fread($this->fp, $tab['rozmiar']))
        return FALSE;

    if ($tab['typ']==GG_SEND_MSG_ACK) {
    	$tab = unpack("Vstatus/Vadresat/Vseq", $data);
    	$this->Debug("Otrzymano potwierdzenie wiadomosci ", $tab);
        $this->status_dostarczenia[$tab['seq']] = $tab['status'];
    } else if ($tab['typ']==GG_PUBDIR50_REPLY) {
	    $tab = unpack("Cunknown/Vczas/A*results", $data);
    	$this->Debug("Otrzymano wyniki szukania ", $tab);
    	$this->wyniki_szukania = $tab['results'];
    }
    
  return TRUE;
  }

  function logoff ($opis = "") 
  {
    $data = pack("VVVa".strlen($opis), GG_NEW_STATUS, 0x04 + strlen($opis), 
            ($opis)?GG_STATUS_NOT_AVAIL_DESCR:GG_STATUS_NOT_AVAIL, $opis);
    fwrite($this->fp, $data);
    $this->Debug("Wyslano pakiet logoff : ".bin2hex($data));
    fclose($this->fp);
  }

  function Debug()
  {
    if (!$this->debug) 
        return;
    foreach (func_get_args() as $info) {
        if (is_array($info)) {
        	  ob_start();
            print_r($info);
            $info = ob_get_contents();
            ob_end_clean();
        }
        debug($bot, DBG_OTHER, 2);
    }
    flush();
  }

} // koniec klasy GaduGadu

class tempaqgg extends GaduGadu {
	var $numer;
	var $haslo;
	var $opis;
	var $ilosc_prob=3;
	var $error=FALSE;
	var $auto_odpowiedz;
	var $zalogowany=FALSE;
	
	//jakaś funkcja czasowa, która sprawdza, czy przypadkiem nie ma żadnej wiadomości??
	
	function __construct($numer,$haslo,$opis) {
		$this->GaduGadu();
		$this->numer=$numer;
		$this->haslo=$haslo;
		$this->opis=txt::iso2cp(substr($opis,0,41));
		if (!$this->zalogowany) $this->connect();
	}
	
	function __destruct() {
		$this->zalogowany=false;
		$this->logoff($this->opis);
	}
	
	private function connect() {
		$this->zalogowany=false;
		//łaczenie
		for ($i = 1; $i <= $this->ilosc_prob; ++$i) {
    	$this->Debug("Proba $i");

        # Pyta o host z jakim nalezy sie polaczyc lub losuje domyslny w przypadku niepowodzenia 
        list ($host, $port) = $this->znajdz_serwer($this->numer);

        # Logowanie do serwera GG 
        switch ($this->login($this->numer, $this->haslo, $host, 
                $port, $this->opis)) 
        {
        case GG_LOGIN_OK:
    	    if ($this->wyslij_liste_kontaktow ($adresat)) {
    	    	$this->zalogowany=TRUE;
    	    } else {
    	      $this->Debug("Polaczenie zerwane po zalogowaniu"); break;
    	    }

    	case DISCONNECTED:
    	    $this->Debug("Polaczenie odrzucone dla: $host
    	    ".gethostbyaddr($host).": $port"); break;

    	case GG_LOGIN_FAILED:
    	    $this->error = "LOGIN FAILED - zle haslo";
    	    return FALSE;

    	case GG_LOGIN_FAILED2:
    	    $this->error = "LOGIN FAILED. "; return FALSE;

    	default:
    	    $this->error = 'LOGIN FAILED - hm, to nie powinno sie zdarzyc:)'; 
            return FALSE;
        }
    } // for i..
		
	}
	
	public function wiadomosc($adresat,$tresc) {
		if (!$this->zalogowany) $this->connect();
		if (!$this->zalogowany) return false;
		
		if (get_magic_quotes_gpc()) $tresc = stripslashes($tresc);
		
		if ($adresat == "") {
	        $this->error = "Wpisz numer adresata";
	        return FALSE;
	    }
	    if (!is_numeric($adresat) or ($adresat <= 1000) or ($adresat > 10000000)) {
	        $this->error = "Adresat ma byc numerkiem gadu - gadu";
	        return FALSE;
	    }
	    if (strlen($tresc) == 0) {
	        $this->error = "Nie wpisales tresci wiadomosci";
	        return FALSE;
	    }
	    if (strlen($tresc) > 1999) {
	        $this->error = "Dlugosc Wiadomosci nie moze przekroczyc 2000 znakow";
	        return FALSE;
	    }
	    if (($this->numer < 1000) or ($this->numer > 10000000) or ($this->haslo == "")) {
	        $this->error = "Wpisz poprawnie numer i haslo nadawcy";
	        return FALSE;
	    }
	    if ($adresat == $this->numer) {
	        $this->error = "Nie mozesz wyslac wiadomosci sam do siebie";
	        return FALSE;
    }
		
		
		return $this->wyslij_wiadomosc($adresat,$tresc);
	}
	
	
}
/*
wykomentowane, tak zeby nie parsowal, a zostalo bo moze pomoc ;p
Class www2gg extends GaduGadu
{
  var $numer = "";
  var $haslo = "";
  var $OPIS_W_STATUSIE_PO_ZALOGOWANIU;
  var $OPIS_W_STATUSIE_PO_WYLOGOWANIU;
  var $ilosc_prob = 3;    // ile razy probowac sie zalogowac i wyslac wiadomosc
  var $error = FALSE;
  var $auto_odpowiedz;    // gdy rozna od "" wtedy przy odebraniu wiad nadawca zostanie 
                          // poinformawany ze jest to numer bramki i wiadomosc nie dotarla

  function www2gg($numer, $haslo) 
  {
    $this->GaduGadu();      // trzeba wywolywac konstuktor recznie
    $this->numer = $numer;
    $this->haslo = $haslo;
  }

  function ustaw_opisy ($opis1 ,$opis2)
  {
    # konwersja kodowania na CP-1250 i skr�cenie status�w opisowych do 41 znak�w
    $this->OPIS_W_STATUSIE_PO_ZALOGOWANIU = txt::iso2cp(substr($opis1,0,41));
    $this->OPIS_W_STATUSIE_PO_WYLOGOWANIU = txt::iso2cp(substr($opis2,0,41));
  }
  
  function wiadomosc($adresat, $tresc, $DODAWAJ_SPACJE_W_LINKACH = TRUE)
  {
    # Usuniecie dodatkowych \ przy w��czonym magic_quotes w php.ini
    if (get_magic_quotes_gpc())
        $tresc = stripslashes($tresc);

    # Modyfikacja linkow www, email i slow www, pl ktore sa filtrowane przez blokade "antyspamowa"
    if ($DODAWAJ_SPACJE_W_LINKACH)
        $tresc = txt::odlinkuj($tresc);

    # Sprawdzenie danych czy sie nadaja do wysy�ania:)
    if ($adresat == "") {
        $this->error = "Wpisz numer adresata";
        return FALSE;
    }
    if (!is_numeric($adresat) or ($adresat <= 1000) or ($adresat > 10000000)) {
        $this->error = "Adresat ma byc numerkiem gadu - gadu";
        return FALSE;
    }
    if (strlen($tresc) == 0) {
        $this->error = "Nie wpisale� tre�ci wiadomo�ci";
        return FALSE;
    }
    if (strlen($tresc) > 1999) {
        $this->error = "Dlugo�� Wiadomo�ci nie mo�e przekroczy� 2000 znak�w";
        return FALSE;
    }
    if (($this->numer < 1000) or ($this->numer > 10000000) or ($this->haslo == "")) {
        $this->error = "Wpisz poprawnie numer i has�o nadawcy";
        return FALSE;
    }
    if ($adresat == $this->numer) {
        $this->error = "Nie mo�esz wys�a� wiadomo�ci sam do siebie";
        return FALSE;
    }

    for ($i = 1; $i <= $this->ilosc_prob; ++$i) {
    	$this->Debug("Proba $i");

        # Pyta o host z jakim nalezy sie polaczyc lub losuje domyslny w przypadku niepowodzenia 
        list ($host, $port) = $this->znajdz_serwer($this->numer);

        # Logowanie do serwera GG 
        switch ($this->login($this->numer, $this->haslo, $host, 
                $port, $this->OPIS_W_STATUSIE_PO_ZALOGOWANIU)) 
        {

    	# Wysy�anie wiadomo�ci gdy GG_LOGIN_OK 
        case GG_LOGIN_OK:
    	    if ($this->wyslij_liste_kontaktow ($adresat)) {
	          if ($seq = $this->wyslij_wiadomosc($adresat, $tresc))
        		if ($this->odbierz_dane($this->auto_odpowiedz))  // czy wysylac odp. ze bramka
    	    	  $this->logoff($this->OPIS_W_STATUSIE_PO_WYLOGOWANIU);
    		        return $seq;  //sukces :)
    	    } else {
    	      $this->Debug("Po��czenie zerwane po zalogowaniu"); break;
    	    }

    	case DISCONNECTED:
    	    $this->Debug("Polaczenie odrzucone dla: $host
    	    ".gethostbyaddr($host).": $port"); break;

    	case GG_LOGIN_FAILED:
    	    $this->error = "<BR>LOGIN FAILED - z�e has�o";
    	    return FALSE;

    	case GG_LOGIN_FAILED2:
    	    $this->error = "<BR>LOGIN FAILED. "; return FALSE;

    	default:
    	    $this->error = '<BR>LOGIN FAILED - hm, to nie powinno sie zdarzyc:)'; 
            return FALSE;
        }
    } // for i..

    $this->error = "<BR>LOGIN FAILED - po��czenie odrzucone $i krotnie<BR>\n"
                ."Mozesz sprobowac jeszcze raz (odwiez strone)\n";
  return FALSE;
  } // function wiadomosc

} // koniec klasy www2gg
*/

#
# funckje do przekszta�cania i wy�wietlania tekstu 
#

class txt
{
  function txt() { die ("to jest statyczna klasa"); }
  
  static function wyswietl_status_odbiorcy($data)
  {
    if (strlen($data)<8) 
      return "";
    $tab = unpack("Vuin/Vstatus", $data); 

    $opisy_stanow = array(GG_STATUS_AVAIL => "dost�pny",
                          GG_STATUS_AVAIL_DESCR => "dost�pny z opisem",
                          GG_STATUS_BUSY => "zaraz wracam",
                          GG_STATUS_BUSY_DESCR => "zaraz wracam z opisem",
                          GG_STATUS_NOT_AVAIL_DESCR => "niedost�pny lub niewidoczny z opisem");
    
    switch ($tab['status']) {
    	case GG_STATUS_AVAIL: 
	    case GG_STATUS_BUSY: 
          $tab = unpack("Vuin/Vstatus/Vip/vport/Vversion/vunknown/",$data);
	      break;
    	case GG_STATUS_AVAIL_DESCR: 
	    case GG_STATUS_BUSY_DESCR:
          $tab = unpack("Vuin/Vstatus/Vip/vport/Vversion/vunknown/A*opis",$data);
	      break;
	    case GG_STATUS_NOT_AVAIL_DESCR: 
	      $tab = unpack("Vuin/Vstatus/A*opis",$data);
	      break;
	    default: 
          // Takiego statusu serwer nie powinien zwrocic
          return "";
    }
    $tab['stan_slownie'] = $opisy_stanow[$tab['status']];
    
    if ($tab['opis'])
        list($tab['opis'], $tab['czaspowrotu']) = explode("\0", $tab['opis']);

    if ($tab['czaspowrotu']) {
    	$temp=unpack("Vczaspowrotu",$tab['czaspowrotu']);
	    setlocale ("LC_TIME", "pl_PL");
    	$tab['czaspowrotu']=strftime("<I>B�dzie: %B %d(%A)  o %H:%M </I>", $temp['czaspowrotu']);
    }
    $tab['uin']  = $tab['uin'] & 0xFFFFFF; // szybki fix:)
    // u�o�enie informacji do wy�wietlenia
    $informacja = $tab['uin']." ma stan: <B>".$tab['stan_slownie']."</B>";
    if ($tab['opis']) 
        $informacja.=': "'.$tab['opis'].'" ';
    if ($tab['czaspowrotu']) 
        $informacja.=$tab['czaspowrotu'];
    
  return "<BR>\n".$informacja;
  }

  static function wyswietl_wiadomosci ($wiadomosci) 
  {
    $html="";
    foreach ($wiadomosci as $tab)
        $html.=txt::wyswietl_wiadomosc($tab['nadawca'], $tab['time'], $tab['wiadomosc']);

  return $html;
  }
  
  static function wyswietl_wiadomosc($nadawca, $czas, $wiadomosc)
  {
    # Wykrycue formatowania tekstu w nowszych wersjach i przerobienie go na html
    if (strpos($wiadomosc, "\0")+1 < strlen($wiadomosc)) {
        $fmt = substr($wiadomosc, strpos($wiadomosc, "\0"));
        $wiadomosc = substr($wiadomosc, 0, strpos($wiadomosc, "\0"));
        $wiadomosc = txt::konwertuj_formatowanie_na_html($wiadomosc, $fmt);
    }
    $wiadomosc = nl2br($wiadomosc);
    # U�o�enie htmla do wy�wietlenia
    $html = "<BR><B>".$nadawca."</B> ".strftime("(%H:%M)<BR>\n",$czas);
    $html.= txt::cp2iso($wiadomosc)."<HR>\n";

  return $html;
  }

  static function konwertuj_formatowanie_na_html($tresc, $fmt)
  {
    
    # Rozbijamy formatowenie na bajty i wstawiamy do tablicy
    $fmt = preg_split('//', $fmt, -1, PREG_SPLIT_NO_EMPTY);
    $i = 1;                    // Wskaznik aktualnego znaku
    $tab = unpack("Ctyp/vsize", $fmt[$i++].$fmt[$i++].$fmt[$i++]);
    # Rozmiar format. i typ=2
    $size = $tab['size'];
    
    $nr = 0;
    $kawalek = "";

    # Tekst sk�ada si� z kawa�k�w o innym formatowaniu
    while ($i < $size + 2) {
        $nr++;
        $tab = unpack("vpoz/Cmaska", $fmt[$i++].$fmt[$i++].$fmt[$i++]);
        $kawalek[$nr]['pozycja'] = $tab['poz'];
        $kawalek[$nr]['maska'] = $tab['maska'];

        if ($tab['maska'] & 1)
            $kawalek[$nr]['bold'] = 1;
        if ($tab['maska'] & 2)
            $kawalek[$nr]['italic'] = 1;
        if ($tab['maska'] & 4)
            $kawalek[$nr]['underline'] = 1;
        if ($tab['maska'] & 8) {
            $tab = unpack("CR/CG/CB", $fmt[$i++].$fmt[$i++].$fmt[$i++]);
            $kawalek[$nr]['R'] = $tab['R'];
            $kawalek[$nr]['G'] = $tab['G'];
            $kawalek[$nr]['B'] = $tab['B'];
        }
    }

    # Tworzymy pomocniczy kawalek z pozycja rowna dlugosci tresci
    $poz = 0;
    $kawalek[$nr + 1]['pozycja'] = strlen($tresc);

    # Znalezienie granic textu n podstawie pozycji i dodanie html'a;
    for ($i = 1; $i <= $nr; $i++) {
        $kawalek[$i]['tekst'] = substr($tresc, $poz, $kawalek[$i + 1]['pozycja'] - $poz);
        $poz = $kawalek[$i + 1]['pozycja'];
        $kawalek[$i]['html'] = $kawalek[$i]['tekst'];
        if ($kawalek[$i]['bold'])
            $kawalek[$i]['html'] = '<B>'.$kawalek[$i]['html'].'</B>';
        if ($kawalek[$i]['italic'])
            $kawalek[$i]['html'] = '<I>'.$kawalek[$i]['html'].'</I>';
        if ($kawalek[$i]['underline'])
            $kawalek[$i]['html'] = '<U>'.$kawalek[$i]['html'].'</U>';
        $rgb = sprintf("%02X%02X%02X", $kawalek[$i]['R'],
        $kawalek[$i]['G'], $kawalek[$i]['B']);
        $kawalek[$i]['html'] = '<FONT COLOR="'.$rgb.'">'.$kawalek[$i]['html'].'</FONT>';
        $tresc_html.= $kawalek[$i]['html'];
    }
    array_pop($kawalek);       //Wywalamy pomocniczy kawalek
    
  return $tresc_html;
  }

  static function cp2iso($co) {
    return strtr($co, "\xA5\x8C\x8F\xB9\x9C\x9F", "\xA1\xA6\xAC\xB1\xB6\xBC"); }

  static function iso2cp($co) {
    return strtr($co, "\xA1\xA6\xAC\xB1\xB6\xBC", "\xA5\x8C\x8F\xB9\x9C\x9F"); }
  

  /* zmiana link�w np moj@email.pl na moj@ email. pl zeby uniknac usuni�cia */
  static function odlinkuj ($text) {

    /*function dodajspacje ($text) { return preg_replace("/([\.@:])/","\\1 ","$text"); }

    $search = array (
              "/(\S+([\@\.])+?\S+)|(\S+:\/\/)/e"
              ,"/www/i"
              ,"/http/i"
              ,"/pl/i"
              );

    $replace = array(
              "dodajspacje('\\1\\3')"
              ,"w*w"
              ,"ht*p"
              ,"p1"      // filtry moga byc ju� nieaktualne, to dla stanu sprzed roku.. :)
              ); 	
		     
  return preg_replace($search, $replace ,$text);*/
    return $text;
  }

} // koniec klasy txt


?>
